package com.skydroid.serialport

import android.content.Context
import android.content.Intent
import android.hardware.usb.UsbDevice
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.appcompat.app.AppCompatActivity
import com.skydroid.fpvlibrary.common.connect.usb.UsbSerialConnection
import com.skydroid.fpvlibrary.common.video.FPVVideoClient
import com.skydroid.fpvlibrary.uartvideo.usb.DeviceFilter
import com.skydroid.fpvlibrary.uartvideo.usb.USBMonitor
import com.skydroid.fpvlibrary.ui.widget.uartvideo.GLHttpVideoSurface
import com.skydroid.fpvlibrary.utils.BusinessUtils

class USBSerialSamplesActivity: AppCompatActivity() {

    private var mUSBMonitor: USBMonitor? = null

    private var uartDevice: UsbDevice? = null

    private var mPreviewDualVideoView: GLHttpVideoSurface? = null

    private var mUsbSerialConnection: UsbSerialConnection? = null

    private var context: Context? = null

    private var fPVVideoImp: FPVVideoClient? = null

    val mainHanlder: Handler by lazy { Handler(Looper.getMainLooper()) }

    //使用 USBMonitor 处理USB连接回调
    private val mOnDeviceConnectListener: USBMonitor.OnDeviceConnectListener =
        object : USBMonitor.OnDeviceConnectListener {
            // USB device attach
            // USB设备插入
            override fun onAttach(device: UsbDevice?) {
                if (deviceHasConnected(device) || uartDevice != null) return
                runOnUiThread {
                    try {
                        if (device == null) {
                            val devices =
                                mUSBMonitor!!.deviceList
                            if (devices.size == 1) {
                                mUSBMonitor!!.requestPermission(devices[0])
                            }
                        } else {
                            mUSBMonitor!!.requestPermission(device)
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }
            }

            // USB device detach
            // USB设备物理断开
            override fun onDettach(device: UsbDevice?) {
                if (!BusinessUtils.deviceIsUartVideoDevice(device)) {
                    return
                }
                if (!deviceHasConnected(device)) {
                    return
                }
                disconnected()
            }

            // USB device has obtained permission
            // USB设备获得权限
            override fun onConnect(
                device: UsbDevice,
                ctrlBlock: USBMonitor.UsbControlBlock?,
                createNew: Boolean
            ) {
                if (!BusinessUtils.deviceIsUartVideoDevice(device)) {
                    return
                }
                if (deviceHasConnected(device)) {
                    return
                }
                synchronized(this) {
                    if (BusinessUtils.deviceIsUartVideoDevice(device)) {
                        if (mUsbSerialConnection!!.openUsbSerial(device)) uartDevice = device
                    }
                }
            }

            // USB device obtained permission failed
            // USB设备权限获取失败
            override fun onCancel() {

            }

            // USB device disconnected
            // USB设备关闭连接
            override fun onDisconnect(
                device: UsbDevice?,
                ctrlBlock: USBMonitor.UsbControlBlock?
            ) {
                if (!BusinessUtils.deviceIsUartVideoDevice(device)) {
                    return
                }
                if (!deviceHasConnected(device)) {
                    return
                }
                disconnected()
            }

        }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_usbserial_samples)
        context = this
        initView()
        initData()
    }

    companion object {
        fun start(context: Context?) {
            context?.startActivity(Intent(context, USBSerialSamplesActivity::class.java))
        }
    }

    private fun initView() {
        mPreviewDualVideoView = findViewById(R.id.video)
    }

    private fun initData() {
        mPreviewDualVideoView?.init()

        mUsbSerialConnection = UsbSerialConnection(context)
        mUsbSerialConnection?.setClientListener(object:UsbSerialConnection.ClientListener{
            override fun onH264Received(bytes: ByteArray?,paySize:Int) {
//                Log.e("onH264Received", String(bytes!!))
                fPVVideoImp?.received(bytes,4,paySize)
            }

            override fun onGPSReceived(bytes: ByteArray?) {
//                Log.e("onH264Received", String(bytes!!))
            }

            override fun onDataReceived(bytes: ByteArray?) {
//                Log.e("onDataReceived", String(bytes!!))
            }

            override fun onDebugReceived(bytes: ByteArray?) {
//                Log.e("onDebugReceived", String(bytes!!))
            }
        })

        fPVVideoImp = FPVVideoClient()
        fPVVideoImp?.setRun(mUsbSerialConnection?.isPlaying()?:false)
        fPVVideoImp?.setDelegate(object :FPVVideoClient.Delegate {
            override fun onStopRecordListener(fileName: String?) {

            }

            override fun onSnapshotListener(fileName: String?) {

            }

            override fun renderI420(frame: ByteArray?, width: Int, height: Int) {
                mPreviewDualVideoView?.renderI420(frame, width?:0, height?:0)
            }

            override fun resetView() {
                mPreviewDualVideoView?.resetView(mainHanlder)
            }

            override fun setVideoSize(picWidth: Int, picHeight: Int) {
                mPreviewDualVideoView?.setVideoSize(picWidth?:0, picHeight?:0,mainHanlder)
            }
        })
        fPVVideoImp?.startPlayback()

        mUSBMonitor = USBMonitor(this, mOnDeviceConnectListener)
        val filters: List<DeviceFilter> = DeviceFilter.getDeviceFilters(this, R.xml.device_filter)
        mUSBMonitor!!.setDeviceFilter(filters)
        mUSBMonitor!!.register()

    }

    private fun deviceHasConnected(device: UsbDevice?): Boolean {
        return device != null && device == uartDevice
    }


    fun bytesToHex(bytes: ByteArray): String? {
        val sb = StringBuffer()
        for (i in bytes.indices) {
            val hex = Integer.toHexString(bytes[i].toInt() and 0xFF)
            if (hex.length < 2) {
                sb.append(0)
            }
            sb.append(hex)
        }
        return sb.toString().toUpperCase()
    }

    @Synchronized
    private fun disconnected() {
        mUsbSerialConnection?.close()
        fPVVideoImp?.stopPlayback()
        uartDevice = null
    }

    override fun onDestroy() {
        super.onDestroy()
        disconnected()
        if (mUSBMonitor != null) {
            mUSBMonitor!!.unregister()
            mUSBMonitor!!.destroy()
            mUSBMonitor = null
        }
    }
}